﻿using Asp.Versioning;
using FlyingEye.ControllerServices;
using FlyingEye.Exceptions;
using FlyingEye.Monitors.Models;
using FlyingEye.Monitors.Repositories;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace FlyingEye.Controllers
{
    [Authorize]
    [ControllerName("NumericValueMonitorClient")]
    [ApiVersion("1.0")]
    [Route("api/device-monitor-service/v{version:apiVersion}/numeric-value-monitor-clients")]
    public class NumericValueMonitorClientController : DefaultController
    {
        private readonly INumericValueMonitorClientRepository _valueDataClientMonitorPointRepository;

        public NumericValueMonitorClientController(INumericValueMonitorClientRepository valueDataClientMonitorPointRepository)
        {
            _valueDataClientMonitorPointRepository = valueDataClientMonitorPointRepository;
        }

        [HttpGet("{id}", Name = "GetByNumericValueMonitorClientId")]
        public async Task<ActionResult<NumericValueMonitorClientResponse>> GetAsync(Guid id)
        {
            return await this.GetInvokeAsync(async () =>
            {
                var model = await _valueDataClientMonitorPointRepository.GetAsync(id);

                return ObjectMapper.Map<NumericValueMonitorClientModel, NumericValueMonitorClientResponse>(model);
            });
        }

        [HttpGet]
        public async Task<ActionResult<List<NumericValueMonitorClientResponse>>> GetListAsync()
        {
            return await this.GetInvokeAsync(async () =>
            {
                var list = await _valueDataClientMonitorPointRepository.GetListAsync();
                return ObjectMapper.Map<List<NumericValueMonitorClientModel>, List<NumericValueMonitorClientResponse>>(list);
            });
        }

        [HttpPut]
        public async Task<ActionResult<NumericValueMonitorClientResponse>> UpdateAsync([FromBody] UpdateNumericValueMonitorClientRequest request)
        {
            if (request.Id == Guid.Empty)
            {
                throw new AppArgumentValidationException("ID 不能为空");
            }

            if (request.ReadNumericValueTaskId == Guid.Empty)
            {
                throw new AppArgumentValidationException("监听任务 ID 不能为空");
            }

            if (string.IsNullOrWhiteSpace(request.ClientName))
            {
                throw new AppArgumentValidationException("监听点客户端名称不能为空");
            }

            return await this.PutInvokeAsync(async () =>
            {
                var model = ObjectMapper.Map<UpdateNumericValueMonitorClientRequest, NumericValueMonitorClientModel>(request);
                var result = await _valueDataClientMonitorPointRepository.UpdateAsync(model);
                return ObjectMapper.Map<NumericValueMonitorClientModel, NumericValueMonitorClientResponse>(result);
            });
        }

        [HttpDelete("{id}")]
        public async Task<NoContentResult> DeleteAsync(Guid id)
        {
            return await this.DeleteInvokeAsync(async () =>
            {
                await _valueDataClientMonitorPointRepository.DeleteAsync(id);
            });
        }

        [HttpPost]
        public async Task<ActionResult<NumericValueMonitorClientResponse>> InsertAsync([FromBody] CreateNumericValueMonitorClientRequest request)
        {
            if (request.ReadNumericValueTaskId == Guid.Empty)
            {
                throw new AppArgumentValidationException("监听任务 ID 不能为空");
            }

            if (string.IsNullOrWhiteSpace(request.ClientName))
            {
                throw new AppArgumentValidationException("监听点客户端名称不能为空");
            }

            return await this.InsertInvokeAsync(async () =>
            {
                var model = ObjectMapper.Map<CreateNumericValueMonitorClientRequest, NumericValueMonitorClientModel>(request);
                var result = await _valueDataClientMonitorPointRepository.InsertAsync(model);
                return ObjectMapper.Map<NumericValueMonitorClientModel, NumericValueMonitorClientResponse>(result);
            }, "GetByNumericValueMonitorClientId", x => new { x.Id });
        }
    }
}
